home *** CD-ROM | disk | FTP | other *** search
- /*
- * WINFO2ICON A companion utility to wIconSetter and wIconify.
- * wInfo2Icon converts a Workbench .info file into
- * an icon file usable by wIconSetter.
- *
- * Copyright 1990 by Davide P. Cervone, all rights reserved.
- * You may use this code, provided this copyright notice is kept intact.
- */
-
- #include "wInfo2Icon.h"
-
- static char *program = PROGRAM;
- static char *copyright = COPYRIGHT;
-
- struct IconBase *IconBase;
-
- static struct DiskObject *theInfo; /* Data read from the .info file */
- static long IconFile; /* the output icon file */
- static struct BitMap theBitMap; /* a bitmap for the image */
- static struct BitMap theMaskMap; /* a bitmap for the mask image */
- static int theWidth,theHeight,theDepth; /* size of the image */
- static struct TmpRas theTmpRas; /* needed for FloodFill */
-
- static char *InfoName; /* name of the info file */
- static char *IconName; /* name of the icon file */
-
- static char *Hex = "0123456789abcdef)!@#$%^&*(ABCDEF";
- #define MAXHEX 32
- #define MAXLINE 132
-
- #define BLT_INVERT 0x50
- #define FLOOD_SAME 1
-
-
- /*
- * FreePlanes()
- *
- * Free each bitplane of the bitmap and free the temporary raster.
- */
-
- static void FreePlanes()
- {
- short i;
-
- for (i=0; i<theDepth; i++)
- {
- if (theBitMap.Planes[i])
- FreeRaster(theBitMap.Planes[i],theWidth,theHeight);
- theBitMap.Planes[i] = NULL;
- }
- if (theTmpRas.RasPtr) FreeRaster(theTmpRas.RasPtr,theWidth,theHeight);
- theTmpRas.RasPtr = NULL;
- }
-
-
- /*
- * DoExit()
- *
- * General purpose error-exit routine. Print an error message if one was
- * supplied (it can have up to three parameters), and then clean up any
- * memory, libraries, etc. that need to be handled before exiting.
- */
-
- void DoExit(s,x1,x2,x3)
- char *s, *x1, *x2, *x3;
- {
- long status = EXIT_OK;
-
- if (s != NULL)
- {
- printf(s,x1,x2,x3);
- printf("\n");
- status = EXIT_ERROR;
- }
- FreePlanes();
- if (IconFile) fclose(IconFile);
- if (theInfo) FreeDiskObject(theInfo);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (GfxBase) CloseLibrary(GfxBase);
- if (IconBase) CloseLibrary(IconBase);
- exit(status);
- }
-
-
- /*
- * CheckLibOpen()
- *
- * Call OpenLibrary() for the specified library, and check that the
- * open succeeded.
- */
-
- static void CheckLibOpen(lib,name,rev)
- APTR *lib;
- char *name;
- int rev;
- {
- extern APTR OpenLibrary();
-
- if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
- DoExit("Can't open %s",name);
- }
-
-
- /*
- * GetPlanes()
- *
- * Set the size of the image, but add an extra bitplane (for the mask)
- * Initialize the BitMaps
- * Get the bitplanes for the BitMap
- * Make the mask BitMap share the last bitplane
- * Get a temporary raster (for FloodFill)
- */
-
- static void GetPlanes(w,h,d)
- int w,h,d;
- {
- short i;
-
- theWidth = w; theHeight = h; theDepth = d+1;
- InitBitMap(&theBitMap,theDepth,w,h);
- InitBitMap(&theMaskMap,1,w,h);
- for (i=0; i<theDepth; i++)
- {
- theBitMap.Planes[i] = AllocRaster(w,h);
- if (theBitMap.Planes[i] == NULL) DoExit("Can't Get BitPlane %d",i);
- }
- theMaskMap.Planes[0] = theBitMap.Planes[d];
- theTmpRas.RasPtr = (UBYTE *)AllocRaster(w,h);
- if (theTmpRas.RasPtr == NULL) DoExit("Can't Get TmpRas for FloodFill");
- theTmpRas.Size = RASSIZE(theWidth,theHeight);
- }
-
-
- /*
- * DoBackFill()
- *
- * Invert the image's bitmap (so the Mask bitplane becomes all 1's) and flood
- * the RastPort with 0's starting at the upper left-hand corner. Since there
- * is a one pixel border around the actual image data, this does a flood fill
- * from the outside of the image into the interior. The Mask bitplane then
- * has 0's exactly outside the image itself.
- */
-
- static void DoBackFill(theRastPort)
- struct RastPort *theRastPort;
- {
- BltBitMap(theRastPort->BitMap,0,0,theRastPort->BitMap,0,0,
- theWidth,theHeight,BLT_INVERT,0xFF,NULL);
- SetAPen(theRastPort,0L);
- SetDrMd(theRastPort,JAM1);
- Flood(theRastPort,FLOOD_SAME,0,0);
- }
-
-
- /*
- * WriteBitMap()
- *
- * Clip the width to the maximum we can write
- * For each row in the image
- * And each column in each row
- * Get the pen color of the pixel
- * Store the HEX digit in the line buffer
- * End the line and print it to the file
- */
-
- static void WriteBitMap(theRastPort,Width,Height,x,y)
- struct RastPort *theRastPort;
- int Width,Height,x,y;
- {
- short h,w;
- int pen;
- char Line[MAXLINE];
-
- if (Width > MAXLINE) Width = MAXLINE;
-
- for (h=0; h<Height; h++)
- {
- for (w=0; w<Width; w++)
- {
- pen = ReadPixel(theRastPort,w+x,h+y) % MAXHEX;
- Line[w] = Hex[pen];
- }
- Line[w] = 0;
- fprintf(IconFile,"\n ");
- fprintf(IconFile,Line);
- }
- fprintf(IconFile,"\n");
- }
-
-
- /*
- * WriteImage()
- *
- * If there is an image to write,
- * Free any bitplanes that we already got
- * Get the number of planes we need to write and count the depth
- * Get the bitplanes for a slightly larger image (leave a border around it)
- * Set up the RastPort to use the BitMap and TmpRas
- * Clear the bitmap and temporarily remove the extra bitplane
- * Draw the image into the prepared bitmap, leaving a 1-pixel border
- * Write the image to the file
- * If we are also writing the mask,
- * Put back the extra bitplane
- * Do the backfill stuff to get the mask
- * Write the MASK command
- * Use the mask bitmap and write the mask to the file
- */
-
- static void WriteImage(theImage,MaskIt)
- struct Image *theImage;
- int MaskIt;
- {
- int depth;
- int mask;
- struct RastPort theRastPort;
-
- if (theImage)
- {
- FreePlanes();
- mask = theImage->PlanePick | theImage->PlaneOnOff;
- for (depth=0; mask; depth++) mask >>= 1;
- if (depth > 5) depth = 5;
- GetPlanes(theImage->Width+2,theImage->Height+2,depth);
- InitRastPort(&theRastPort);
- theRastPort.BitMap = &theBitMap;
- theRastPort.TmpRas = &theTmpRas;
- SetRast(&theRastPort,0L); theBitMap.Depth--;
- DrawImage(&theRastPort,theImage,1,1);
- WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
- if (MaskIt)
- {
- theBitMap.Depth++;
- DoBackFill(&theRastPort);
- fprintf(IconFile,"\nMASK:\n");
- theRastPort.BitMap = &theMaskMap;
- WriteBitMap(&theRastPort,theImage->Width,theImage->Height,1,1);
- }
- }
- }
-
-
- /*
- * WriteIcon()
- *
- * Get the WB icon's Gadget structure
- * Write the identification header to the file
- * If the gadget has an image,
- * Write the IMAGE command to the file
- * Write the image itself, and write the mask if it is a BACKFILL icon
- * Now check the highlight bits:
- * GADGHIMAGE:
- * If there is a select image,
- * Write the SELECT command, and write the image data and mask
- * GADGHNONE:
- * If the gadget had an image,
- * Write it as the select image (this way it looks the same selected
- * as unselected) and write the mask as well, for good measure
- * (the WB doesn't do this, but we will, since it's easy)
- * Don't write anything else for the other highlight types
- * (we've already taken care of GADGHBACKFILL, and GADGHCOMP is the
- * default function of wIconify).
- */
-
- static void WriteIcon()
- {
- struct Gadget *theGadget = &(theInfo->do_Gadget);
-
- fprintf(IconFile,"/*\n * %s\n *\n",IconName);
- fprintf(IconFile," * An Icon created by %s\n",program);
- fprintf(IconFile," * From the Workbench icon %s.info\n",InfoName);
- fprintf(IconFile," */\n");
-
- if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
- {
- fprintf(IconFile,"\nIMAGE:\n");
- WriteImage(theGadget->GadgetRender,
- (theGadget->Flags & GADGHIGHBITS) == GADGBACKFILL);
- }
- switch(theGadget->Flags & GADGHIGHBITS)
- {
- case GADGHIMAGE:
- if (theGadget->SelectRender)
- {
- fprintf(IconFile,"\nSELECT:\n");
- WriteImage(theGadget->SelectRender,TRUE);
- }
- break;
-
- case GADGHNONE:
- if ((theGadget->Flags & GADGIMAGE) && theGadget->GadgetRender)
- {
- fprintf(IconFile,"\nSELECT:\n");
- WriteImage(theGadget->GadgetRender,TRUE);
- }
- break;
-
- case GADGBACKFILL:
- case GADGHCOMP:
- break;
- }
- }
-
-
- /*
- * main()
- *
- * If run from the WB, sinply exit
- * Show the usage if there are not the right number of arguments
- * Otherwise, get the file names
- * Open the needed libraries
- * Get the info from the .info file, if possible
- * Open the icon file for writing, if possible
- * Write the icon to the file
- */
-
- void main(argc,argv)
- int argc;
- char **argv;
- {
- if (argc == 0) DoExit(NULL);
- if (argc != 3) DoExit("Usage: %s",USAGE);
- InfoName = argv[1];
- IconName = argv[2];
-
- CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
- CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
- CheckLibOpen(&IconBase,"icon.library",ICON_REV);
-
- theInfo = GetDiskObject(InfoName);
- if (theInfo == NULL) DoExit("Can't read Info file '%s.info'",InfoName);
- IconFile = fopen(IconName,"w");
- if (IconFile == NULL) DoExit("Can't write Icon file '%s'",IconName);
- WriteIcon();
-
- DoExit(NULL);
- }
-